This is a Work in Progress and does not work exactly as the standard CCM work.
fromcryptopals_libimport*fromaes_libimportAESimportosdefCBC_MAC(enc_obj,message,iv=None):#First Block is the IV
cipher_block=ivifiv==None:cipher_block=b"\x00"*enc_obj.block_sizeblocks=to_blocks(message,enc_obj.block_size)forblockinblocks:#print(block, cipher_block)
xor_block=fixedlen_xor(block,cipher_block)cipher_block=enc_obj.aes_block_encryption(xor_block)#Do regular CBC Encryption but the MAC is the last block
returncipher_blockdefproper_impl(header,data,key,nonce):importjsonfrombase64importb64encodefromCrypto.CipherimportAESfromCrypto.Randomimportget_random_bytescipher=AES.new(bytes(key),AES.MODE_CCM,nonce=nonce)cipher.update(header)ciphertext, tag=cipher.encrypt_and_digest(data)json_k=['nonce','header','ciphertext','tag']json_v=[x.hex()forxin(cipher.nonce,header,ciphertext,tag)]result=json.dumps(dict(zip(json_k,json_v)))returnresultif__name__=='__main__':key=[0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]nonce=os.urandom(16)plaintext=add_PKCS7_pad(b"Message Data",16)aes_obj=AES(key)mac_plaintext=CBC_MAC(AES(key),plaintext,b"\x00"*16)cypher_text=aes_obj.ctr_encryption(nonce,plaintext+mac_plaintext)print(f"cypher_text: {cypher_text.hex()}")#print(f"mac_plaintext: {mac_plaintext.hex()} ")
print(proper_impl(b"",plaintext,key,nonce[0:9]))